package com.lanxin.jet.controllers;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.lanxin.jet.beans.ResourceBean;
import com.lanxin.jet.services.ResourceService;
import com.lanxin.jet.services.UserService;
import com.lanxin.jet.tools.JetDate;
import com.lanxin.jet.tools.JetResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import net.coobird.thumbnailator.Thumbnails;

@RestController
@RequestMapping("/resource")
@PropertySource("classpath:config.properties")
public class ResourceController {

    @Value("${jet.upload.path}")
    private String uploadPath = "";

    @Autowired
    private ResourceService resourceService;

    @Autowired
    private UserService userService;

    /**
     * 上传文件
     * @param response
     * @param file      文件数据
     * @param bid       文件从属id
     */
    @RequestMapping(value = "/upload.do", method = RequestMethod.POST)
    public Map<String, Object> uploadFile(@RequestParam("file") MultipartFile file, @RequestParam(value = "bid", required = false) String bid) {
        boolean flag = false;
        JetResponse jr = new JetResponse();
        String extName = "";
        String savePath = "";
        if (!file.isEmpty()) {
            String fileName = file.getOriginalFilename();
            extName = fileName.substring(fileName.lastIndexOf(".") + 1);
            //用年月日作为子路径
            SimpleDateFormat dateFormat = new SimpleDateFormat("yy/MM/dd/");
            savePath = dateFormat.format(new Date()) + JetDate.uniqid() + "." + extName;
            File dest = new File(uploadPath + savePath);
            if (!dest.getParentFile().exists()) {
                dest.getParentFile().mkdirs();
            }
            try {
                file.transferTo(dest);
                flag = true;
            } catch (IOException e) {
                //e.printStackTrace();
                jr.error(JetResponse.RES_UNKNOW, "上传遇到未知错误");
            }
        }
        if (flag) {
            if (bid == null) {
                bid = "";
            }
            resourceService.insert(bid, extName, savePath, file.getSize());
            jr.success(savePath);
        } else {
            jr.error(JetResponse.RES_FAIL);
        }
        return jr.map();
    }

    /**
     * 输出图片
     * @param request
     * @param response
     */
    @RequestMapping("/image/**")
    public void image(HttpServletRequest request, HttpServletResponse response) {
        JetResponse jr = new JetResponse();
        String uri = request.getRequestURI();
        if (uri.length() > 15) {
            String path = uri.substring(16);
            String truePath = path;
            int width = 0, height = 0;
            int i,p;
            if ((i = path.indexOf("@")) != -1) {
                truePath = path.substring(0, i);
                //解析缩略参数
                String params = path.substring(truePath.length()+1);
                if ((p = params.indexOf("-")) != -1) {
                    width = Integer.parseInt(params.substring(0, p));
                    height = Integer.parseInt(params.substring(p + 1));
                } else {
                    width = Integer.parseInt(params);
                    height = width;
                }
            }
            //加载资源
            File source = new File(uploadPath + truePath);
            if (source.exists()) {
                File file;
                String extName = truePath.substring(truePath.lastIndexOf(".") + 1);
                if (width > 0 || height > 0) {
                    String tempFileName = uploadPath + "temps/" + truePath.substring(truePath.lastIndexOf("/") + 1, truePath.lastIndexOf("."));
                    if (width > 0) {
                        tempFileName += "-" + width;
                    }
                    if (height > 0) {
                        tempFileName += "-" + height;
                    }
                    tempFileName += "." + extName;
                    file = new File(tempFileName);
                    if (! file.exists()) {
                        if (! file.getParentFile().exists()) {
                            file.getParentFile().mkdirs();
                        }
                        //从源文件中裁剪资源并保存
                        try {
                            Thumbnails.of(source).size(width, height).toFile(file);
                        } catch (IOException e) {
                            //e.printStackTrace();
                            jr.error(JetResponse.RES_UNKNOW, "图片裁剪阶段遇到未知错误");
                        }
                    }
                } else {
                    file = source;
                }
                //渲染输出
                boolean flag = true;
                if (extName.equalsIgnoreCase("jpg") || extName.equalsIgnoreCase("jpeg")) {
                    response.setContentType("image/jpeg");
                } else if (extName.equalsIgnoreCase("png")) {
                    response.setContentType("image/png");
                } else {
                    flag = false;
                    jr.error(JetResponse.RES_PARAMF, "图片格式必须是JPG或者PNG");
                }
                if (flag) {
                    try {
                        byte[] buffer = new byte[2048];
                        FileInputStream fileInputStream = new FileInputStream(file);
                        BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
                        OutputStream outputStream = response.getOutputStream();
                        int c = 0;
                        while ((c = bufferedInputStream.read(buffer)) > 0) {
                            outputStream.write(buffer, 0, c);
                        }
                        outputStream.close();
                        bufferedInputStream.close();
                        fileInputStream.close();
                    } catch (IOException e) {
                        //e.printStackTrace();
                        jr.error(JetResponse.RES_UNKNOW, "图片渲染阶段遇到未知错误");
                    }
                } else {
                    jr.error(JetResponse.RES_FAIL, "输出失败");
                }
            } else {
                jr.error(JetResponse.RES_NOTHAS, "资源不存在");
            }
        } else {
            jr.error(JetResponse.RES_PARAMF);
        }
    }

    /**
     * 输出文件
     * @param request
     * @param response
     */
    @RequestMapping("/output/**")
    public void output(HttpServletRequest request, HttpServletResponse response) {
        JetResponse jr = new JetResponse();
        String uri = request.getRequestURI();
        if (uri.length() > 16) {
            String path = uri.substring(17);
            String extName = path.substring(path.lastIndexOf(".") + 1);
            File file = new File(uploadPath + path);
            if (file.exists()) {
                if (extName.equalsIgnoreCase("jpg") || extName.equalsIgnoreCase("jpeg")) {
                    response.setContentType("image/jpeg");
                } else if (extName.equalsIgnoreCase("png")) {
                    response.setContentType("image/png");
                } else {
                    String fileName = path.substring(path.lastIndexOf("/") + 1);
                    response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
                    response.setContentType("application/octet-stream");
                }
                byte[] buffer = new byte[2048];
                FileInputStream fileInputStream;
                BufferedInputStream bufferedInputStream;
                try {
                    fileInputStream = new FileInputStream(file);
                    bufferedInputStream = new BufferedInputStream(fileInputStream);
                    OutputStream outputStream = response.getOutputStream();
                    int i = 0;
                    while((i = bufferedInputStream.read(buffer)) > 0) {
                        outputStream.write(buffer, 0, i);
                    }
                    outputStream.close();
                    bufferedInputStream.close();
                    fileInputStream.close();
                } catch (IOException e) {
                    //e.printStackTrace();
                    jr.error(JetResponse.RES_UNKNOW, "资源输出阶段遇到未知错误");
                }
            } else {
                jr.error(JetResponse.RES_NOTHAS, "资源不存在");
            }
        } else {
            jr.error(JetResponse.RES_PARAMF);
        }
    }

    /**
     * 统计资源文件数量
     * @param bid
     * @param keyword
     * @param response
     */
    @RequestMapping(value = "/getCount.do", method = RequestMethod.POST)
    public Map<String, Object> getCount(String bid, String keyword){
        JetResponse jr = new JetResponse();
        jr.success(resourceService.count(bid, keyword));
        return jr.map();
    }

    /**
     * 获取资源文件列表
     * @param offset
     * @param limit
     * @param bid
     * @param keyword
     * @param response
     */
    @RequestMapping(value = "/getList.do", method = RequestMethod.POST)
    public Map<String, Object> getList(int offset, int limit, String bid, String keyword) {
        JetResponse jr = new JetResponse();
        jr.success(resourceService.getList(offset, limit, bid, keyword));
        return jr.map();
    }

    /**
     * 设置文件名
     * @param session
     * @param response
     * @param id
     * @param name
     */
    @RequestMapping(value = "/setName.do", method = RequestMethod.POST)
    public Map<String, Object> setName(HttpSession session, String id, String name) {
        JetResponse jr = new JetResponse();
        if (userService.checkRole(session, UserService.ROLE_RESOURCE)) {
            if (!id.isEmpty()) {
                ResourceBean resource = resourceService.get(id);
                if (resource != null) {
                    resource.setName(name);
                    resourceService.update(resource);
                    jr.success();
                } else {
                    jr.error(JetResponse.RES_NOTHAS);
                }
            } else {
                jr.error(JetResponse.RES_PARAMF);
            }
        } else {
            jr.error(JetResponse.RES_TOKENF);
        }
        return jr.map();
    }

    /**
     * 设置类目下文件排序
     * @param session
     * @param response
     * @param id
     * @param sort
     */
    @RequestMapping(value = "/setSort.do", method = RequestMethod.POST)
    public Map<String, Object> setSort(HttpSession session, String id, int sort) {
        JetResponse jr = new JetResponse();
        if (userService.checkRole(session, UserService.ROLE_RESOURCE)) {
            if (!id.isEmpty()) {
                ResourceBean resource = resourceService.get(id);
                if (resource != null) {
                    resource.setSort(sort);;
                    resourceService.update(resource);
                    jr.success();
                } else {
                    jr.error(JetResponse.RES_NOTHAS);
                }
            } else {
                jr.error(JetResponse.RES_PARAMF);
            }
        } else {
            jr.error(JetResponse.RES_TOKENF);
        }
        return jr.map();
    }

    /**
     * 根据id删除资源
     * @param id
     * @param response
     */
    @RequestMapping(value = "/delete.do", method = RequestMethod.POST)
    public Map<String, Object> delete(String id, HttpSession session) {
        JetResponse jr = new JetResponse();
        if (userService.checkRole(session, UserService.ROLE_RESOURCE)) {
            if (!id.isEmpty()) {
                ResourceBean resource = resourceService.get(id);
                if (resource != null) {
                    File file = new File(uploadPath + resource.getPath());
                    if (file.exists()) {
                        file.delete();
                    }
                    resourceService.delete(id);
                    jr.success();
                } else {
                    jr.error(JetResponse.RES_NOTHAS, "资源文件不存在");
                }
            } else {
                jr.error(JetResponse.RES_PARAMF);
            }
        } else {
            jr.error(JetResponse.RES_TOKENF);
        }
        return jr.map();
    }
}